0%

岭回归 (L2)、lasso 回归 (L1)、ElasticNet 讲解 (算法 + 案例)

1.L2 正则化 (岭回归)

1.1 问题

想要理解什么是正则化,首先我们先来了解上图的方程式。当训练的特征和数据很少时,往往会造成欠拟合的情况,对应的是左边的坐标;而我们想要达到的目的往往是中间的坐标,适当的特征和数据用来训练;但往往现实生活中影响结果的因素是很多的,也就是说会有很多个特征值,所以训练模型的时候往往会造成过拟合的情况,如右边的坐标所示。

1.2 公式

以图中的公式为例,往往我们得到的模型是:,为了能够得到中间坐标的图形,肯定是希望越小越好,因为这两项越小就越接近于 0,就可以得到中间的图形了。

对应的损失函数也加上这个惩罚项 (为了惩罚):假设

  • -y%5Ei)%5E2%2B1000%5Ctheta_3%5E2%2B1000%5Ctheta_4%5E2%5D)>)

为了求得最小值,使值趋近于 0,这就达到了我们的目的,得到中间坐标的方程。

把以上公式通用化得:

  • -y%5Ei)%5E2%2B%5Clambda%5Csum_%7Bj%3D1%7D%5E%7Bn%7D%5Ctheta_j%5E2%5D)>)

相当于在原始损失函数中加上了一个惩罚项 (项)

这就是防止过拟合的一个方法,通常叫做 L2 正则化,也叫作岭回归。

1.3 对应图形

我们可以简化 L2 正则化的方程:

表示原始的损失函数,咱们假设正则化项为:>)

我们不妨回忆一下圆形的方程:%5E2%2B(y-b)%5E2%3Dr%5E2>)

其中 (a,b) 为圆心坐标,r 为半径。那么经过坐标原点的单位元可以写成:

正和 L2 正则化项一样,同时,机器学习的任务就是要通过一些方法(比如梯度下降)求出损失函数的最小值。

此时我们的任务变成在 L 约束下求出取最小值的解。

求解的过程可以画出等值线。同时 L2 正则化的函数 L 也可以在的二维平面上画出来。如下图:

L 表示为图中的黑色圆形,随着梯度下降法的不断逼近,与圆第一次产生交点,而这个交点很难出现在坐标轴上。

这就说明了 L2 正则化不容易得到稀疏矩阵,同时为了求出损失函数的最小值,使得 w1 和 w2 无限接近于 0,达到防止过拟合的问题。

1.4 使用场景

只要数据线性相关,用 LinearRegression 拟合的不是很好,需要正则化,可以考虑使用岭回归 (L2), 如何输入特征的维度很高, 而且是稀疏线性关系的话, 岭回归就不太合适, 考虑使用 Lasso 回归。

1.5 代码实现

GitHub 代码 —L2 正则化

2.L1 正则化 (lasso 回归)

2.1 公式

L1 正则化与 L2 正则化的区别在于惩罚项的不同:

  • -y%5Ei)%5E2%2B%5Clambda%5Csum_%7Bj%3D1%7D%5E%7Bn%7D%7C%5Ctheta%7C%5D)>)

L1 正则化表现的是的绝对值,变化为上面提到的 w1 和 w2 可以表示为:

  • >)

2.2 对应图形

求解的过程可以画出等值线。同时 L1 正则化的函数也可以在的二维平面上画出来。如下图:

惩罚项表示为图中的黑色棱形,随着梯度下降法的不断逼近,与棱形第一次产生交点,而这个交点很容易出现在坐标轴上。这就说明了 L1 正则化容易得到稀疏矩阵。

2.3 使用场景

L1 正则化 (Lasso 回归) 可以使得一些特征的系数变小, 甚至还使一些绝对值较小的系数直接变为 0,从而增强模型的泛化能力 。对于高纬的特征数据, 尤其是线性关系是稀疏的,就采用 L1 正则化 (Lasso 回归), 或者是要在一堆特征里面找出主要的特征,那么 L1 正则化(Lasso 回归) 更是首选了。

2.4 代码实现

GitHub 代码 —L1 正则化

3.ElasticNet 回归

3.1 公式

ElasticNet 综合了 L1 正则化项和 L2 正则化项,以下是它的公式:

  • -y%5Ei)%5E2%2B%5Clambda%5Csum%7Bj%3D1%7D%5E%7Bn%7D%5Ctheta_j%5E2%5D%2B%5Clambda%5Csum%7Bj%3D1%7D%5E%7Bn%7D%7C%5Ctheta%7C)>)

3.2 使用场景

ElasticNet 在我们发现用 Lasso 回归太过 (太多特征被稀疏为 0), 而岭回归也正则化的不够(回归系数衰减太慢) 的时候,可以考虑使用 ElasticNet 回归来综合,得到比较好的结果。

3.3 代码实现

1
2
3
4
5
6
from sklearn import linear_model
#得到拟合模型,其中x_train,y_train为训练集
ENSTest = linear_model.ElasticNetCV(alphas=[0.0001, 0.0005, 0.001, 0.01, 0.1, 1, 10], l1_ratio=[.01, .1, .5, .9, .99], max_iter=5000).fit(x_train, y_train)
#利用模型预测,x_test为测试集特征变量
y_prediction = ENSTest.predict(x_test)
复制代码